package net.scala.chapter4.c

/**
 * Scala 允许通过“+/-”定义类型参数的协变性，
 * 1. 用“+”放在类型参数前表示构造子对于该参数是协变的;
 * 2. “-”则表示逆协变;
 * 3. 没有任何符号则表示非协变。
 *
 * @author Barudisshu
 * @tparam A 替换的数据类型
 */
sealed abstract class Maybe[+A] {
  def isEmpty: Boolean
  def get: A
  // 添加类型参数的边界，类型参数下界就是A
  def getOrElse[B >: A](default:B):B = {
    if(isEmpty) default else get
  }
  // 类型参数的上界就是Maybe[_]
  def defaultToNull[B <: Maybe[_]](p: B) = {
    p.getOrElse(null)
  }
}

final case class Just[A](value: A) extends Maybe[A] {
  def isEmpty = false
  def get = value
}

case object Nil extends Maybe[Nothing] {
  def isEmpty = true
  def get = throw new NoSuchElementException("Nil.get")
}
